<template>
  <div class="pf-flow-prop-condition" id="js-properties-panel-custom">
    <pf-form :config="formConfig" :model="formData" @changeEvent="formChange"></pf-form>
  </div>
</template>

<script lang="ts">
import { defineComponent, nextTick, onMounted, ref, Ref, toRefs, watch } from 'vue';
import { buildFlowConditionInfo } from '@/views/page-config/flow/custom-properties/form-data';
import { emptyForm, FormTypeEnum } from 'pf-component';
import { modeler, TaskName } from '@/views/page-config/flow/flow-modeler';

export default defineComponent({
  name: 'FlowCondition',
  props: ['businessObject'],
  setup(props) {
    const bo = toRefs<any>(props).businessObject;
    const activeName: Ref = ref('');
    const elementBusinessObject: Ref = ref('');
    const elementType: Ref = ref('');
    const elementId: Ref = ref('');
    const formVisible: Ref<boolean> = ref(true);
    const conditionFormVisible: Ref<boolean> = ref(true);
    const idEditDisabled: Ref<boolean> = ref(true);

    const resetFlowCondition = () => {
      const bpmnElement = modeler.getActiveElement();
      const bpmnElementSource = bpmnElement.source;
      const bpmnElementSourceRef = bpmnElement.businessObject.sourceRef;
      if (
        bpmnElementSourceRef &&
        bpmnElementSourceRef.default &&
        bpmnElementSourceRef.default.id === bpmnElement.id
      ) {
        // 默认
        formData.value.type = 'default';
      } else if (!bpmnElement.businessObject.conditionExpression) {
        // 普通
        formData.value.type = 'normal';
      } else {
        // 带条件
        const conditionExpression = bpmnElement.businessObject.conditionExpression;
        Object.assign(formData.value, { ...conditionExpression, type: 'condition' });
        // resource 可直接标识 是否是外部资源脚本
        if (formData.value.resource) {
          formData.value.conditionType = 'script';
          formData.value.scriptType = 'externalScript';
          return;
        }
        if (conditionExpression.language) {
          formData.value.conditionType = 'script';
          formData.value.scriptType = 'inlineScript';
          return;
        }
        formData.value.conditionType = 'expression';
      }
    };
    const updateFlowType = (flowType: string) => {
      const bpmnElement = modeler.getActiveElement();
      const bpmnElementSource = bpmnElement.source;
      const bpmnElementSourceRef = bpmnElement.businessObject.sourceRef;
      // 正常条件类
      if (flowType === 'condition') {
        const flowConditionRef = modeler.getModdle().create(TaskName.formalExpr);
        modeler.updateActiveElement({
          conditionExpression: flowConditionRef
        });
        return;
      }
      // 默认路径
      if (flowType === 'default') {
        modeler.updateActiveElement({
          conditionExpression: null
        });
        modeler.updateElement(bpmnElementSource, {
          default: modeler.getActiveElement()
        });
        return;
      }
      // 正常路径，如果来源节点的默认路径是当前连线时，清除父元素的默认路径配置
      if (bpmnElementSourceRef.default && bpmnElementSourceRef.default.id === bpmnElement.id) {
        modeler.updateElement(bpmnElementSource, {
          default: null
        });
      }
      modeler.updateActiveElement({
        conditionExpression: null
      });
    };
    const updateFlowCondition = () => {
      const { conditionType, scriptType, body, resource, language } = formData.value;
      let condition;
      if (conditionType === 'expression') {
        condition = modeler.getModdle().create(TaskName.formalExpr, { body });
      } else {
        if (scriptType === 'inlineScript') {
          condition = modeler.getModdle().create(TaskName.formalExpr, { body, language });
          formData.value.resource = '';
        } else {
          formData.value.body = '';
          condition = modeler.getModdle().create(TaskName.formalExpr, { resource, language });
        }
      }
      modeler.updateActiveElement({ conditionExpression: condition });
    };
    const formConfig = ref(buildFlowConditionInfo());
    const formData: Ref = ref(emptyForm);
    const formChange = (newV: any, prop: string) => {
      if (prop === 'body' || prop === 'language' || prop === 'resource') {
        updateFlowCondition();
      } else if (prop === 'type') {
        if (newV === 'condition') {
          formConfig.value.setHidden('conditionType', false);
        } else {
          formConfig.value.setHidden('conditionType', true);
          formChange('', 'conditionType');
        }
        updateFlowType(newV);
      } else if (prop === 'conditionType') {
        if (newV === 'expression') {
          formConfig.value.setHidden('language', true);
          formConfig.value.setHidden('scriptType', true);
          formConfig.value.setHidden('resource', true);
          formConfig.value.setHidden('body', false);
          const bodyField = formConfig.value.fields.find(f => f.prop === 'body');
          if (bodyField) {
            bodyField.label = '表达式';
            bodyField.type = FormTypeEnum.INPUT.code;
          }
        } else if (newV === 'script') {
          formConfig.value.setHidden('language', false);
          formConfig.value.setHidden('scriptType', false);
          formConfig.value.setHidden('resource', false);
          formConfig.value.setHidden('body', false);
          const bodyField = formConfig.value.fields.find(f => f.prop === 'body');
          if (bodyField) {
            bodyField.label = '脚本';
            bodyField.type = FormTypeEnum.TEXTAREA.code;
          }
        } else {
          formConfig.value.setHidden('language', true);
          formConfig.value.setHidden('scriptType', true);
          formConfig.value.setHidden('resource', true);
          formConfig.value.setHidden('body', true);
        }
      } else if (prop === 'scriptType') {
        if (newV === 'inlineScript') {
          formConfig.value.setHidden('resource', true);
          formConfig.value.setHidden('body', false);
          const bodyField = formConfig.value.fields.find(f => f.prop === 'body');
          if (bodyField) {
            bodyField.label = '脚本';
            bodyField.type = FormTypeEnum.INPUT.code;
          }
        } else if (newV === 'externalScript') {
          formConfig.value.setHidden('resource', false);
          formConfig.value.setHidden('body', true);
        }
      }
    };
    onMounted(() => {});
    watch(
      bo,
      v => {
        if (v) {
          nextTick(() => {
            resetFlowCondition();
          });
        }
      },
      { immediate: false }
    );
    return {
      activeName,
      elementType,
      elementId,
      elementBusinessObject,
      formVisible,
      conditionFormVisible,
      idEditDisabled,
      formConfig,
      formData,
      resetFlowCondition,
      updateFlowCondition,
      updateFlowType,
      formChange
    };
  }
});
</script>
<style scoped lang="scss">
.#{$prefix} {
}
</style>
